package com.daiqee.controller;

import java.text.SimpleDateFormat;

import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.daiqee.controller.support.BaseController;
import com.daiqee.enums.RequestType;
import com.daiqee.pojo.GoodsList;
import com.daiqee.pojo.StockOut;
import com.daiqee.pojo.StockOutFinish;
import com.daiqee.service.impl.GoodsListService;
import com.daiqee.service.impl.StockOutFinishService;
import com.daiqee.service.impl.StockOutService;
import com.daiqee.vo.BootstrapTablePageVO;
import com.daiqee.vo.JsonObjsVO;
import com.daiqee.util.MyBatisPlusUtils;
import com.daiqee.util.WarpperStringUtils;

/**
 * 出库
 * 
 * <br/>
 * @since JDK 1.8
 * @version  V2.1
 * @author RichardTang 
 * @date: 2018年5月7日 下午5:56:02
 * @package com.daiqee.handler
 * @copyright:Copyright (c) 2018, 1245811923@qq.com All Rights Reserved.
 */
@Controller
@RequestMapping("repository/stock-out")
public class StockOutController extends BaseController{

	boolean flag = true; //是否记录该货物,这里的记录的意思是指货物出库完成了 记录出库时候的数量等信息
	
	@Autowired
	private StockOutService stockOutService;
	
	@Autowired
	private GoodsListService goodsListService;
	
	@Autowired
	private StockOutFinishService stockOutFinishService;
	
	/**
	 * 拆分货物-实际出库货物 不出库货物
	 */
	public static Map<String,List<GoodsList>> splitGoods(List<GoodsList> goodsList){
		//存储货物拆分结果
		LinkedHashMap<String,List<GoodsList>> map = new LinkedHashMap<String,List<GoodsList>>();
		//实际出库货物
		ArrayList<GoodsList> outGoods = new ArrayList<GoodsList>();
		//不出库货物
		ArrayList<GoodsList> unOutGoods = new ArrayList<GoodsList>();
		for (GoodsList goods : goodsList) {
			//库存 和 出库 数量做比较 相等代表全部出库
			if (goods.getGoodsListOutStockCount().equals(goods.getGoodsListProductAmount())) {
				//设置出库标识
				goods.setGoodsListOutFlag("Y");
				//添加到需要出库的集合中
				outGoods.add(goods);
			}else {//只出库一部分
				//克隆一个新的对象
				GoodsList copyGoods = goods.clone();
				//设置不出库部分剩余的库存量
				goods.setGoodsListProductAmount(
				    goods.getGoodsListProductAmount() - goods.getGoodsListOutStockCount()
				);
				//设置出库量
				goods.setGoodsListOutStockCount(goods.getGoodsListProductAmount());
				//添加不出库的一部分
				unOutGoods.add(goods);
				/*----------------------------------------*/
				//设置出库部分的出库标记
				copyGoods.setGoodsListOutFlag("Y");
				//设置出库库存和数量 库存数 == 出库数
				copyGoods.setGoodsListProductAmount(copyGoods.getGoodsListOutStockCount());
				//id置null,避免和不出库的冲突
				copyGoods.setGoodsListProductId(null);
				//设置从那部分订单拆分下来的
				copyGoods.setGoodsListOutStockBackId(goods.getGoodsListProductId());
				//添加出库的一部分
				outGoods.add(copyGoods);
			}
			
		}
		map.put("outGoods", outGoods);
		map.put("unOutGoods", unOutGoods);
		return map;
	}
	
	/**
	 * 添加出库完成货物到记录表中
	 * 
	 * @param outGoodsList
	 * 			出库货物
	 * 
	 * @param orderInfo
	 * 			出库单号信息
	 * 
	 * @return 完成出库货物
	 */
	private boolean addFinishOutProduct(List<GoodsList> outGoodsList,StockOut OrderInfo){
		ArrayList<StockOutFinish> finish = new ArrayList<StockOutFinish>(); 
		for(GoodsList goods : outGoodsList) {
			finish.add(new StockOutFinish(
				OrderInfo.getStockOutOrderNumber(), 
				goods.getGoodsListProductName(), 
				goods.getGoodsListOutStockCount(), 
				goods.getGoodsListProductClass(), 
				goods.getGoodsListProductUnit()
		   ));
		}
		return stockOutFinishService.insertBatch(finish);
	}

	/**
	 * 生成分页条件对象返回BootstrapTablePageVO
	 */
	public BootstrapTablePageVO generatorBootVO(Integer offset,Integer limit,EntityWrapper<GoodsList> ew) {
		Page<GoodsList> page = new Page<GoodsList>(offset,limit);
		Page<GoodsList> pageData = goodsListService.selectPage(page,ew);
		return new BootstrapTablePageVO(pageData.getPages(),pageData.getTotal(),pageData.getRecords());
	}
	
	/**
	 * 查询出库单可以选择的货物,已出库的货物不查询
	 */
	@RequestMapping(value = "/select", method=RequestMethod.GET)
	public Object queryByCondition(GoodsList goods,String dateScope,Integer limit,Integer offset){
		EntityWrapper<GoodsList> ew = 
		    MyBatisPlusUtils.generatorEntityWrapperByEntityAndDateScope(goods, dateScope);
		ew.eq("goods_list_in_stock_status", "入库完成");
		ew.and().eq("goods_list_out_flag", "N");
		return restfulResponse.response(generatorBootVO(offset,limit,ew), RequestType.GET);
	}
	
	/**
	 * 查询指定单子中已经选中的货物
	 */
	@RequestMapping(value = "/selected", method=RequestMethod.GET)
	public Object queryByOrder(String stockOutOrderNumber,
			@RequestParam(value = "limit", defaultValue = "10") Integer limit,
			@RequestParam(value = "offset", defaultValue = "0")Integer offset){
		EntityWrapper<GoodsList> ew = 
		    new EntityWrapper<GoodsList>();
		ew.eq("goods_list_out_flag", "Y");
		ew.eq("goods_list_out_stock_order_number", stockOutOrderNumber);
		return restfulResponse.response(generatorBootVO(offset,limit,ew), RequestType.GET);
	}
	
	/**
	 * 查询已出库货物 指定剩余的货物数量
	 */
	@RequestMapping(value = "/surplus", method=RequestMethod.GET)
	public Object queryByOutGoods(String ids){
		List<String> surplusIds = WarpperStringUtils.getIdListByCommaSplit(ids);
		EntityWrapper<GoodsList> ew = new EntityWrapper<GoodsList>();
		ew.in("goods_list_product_id", surplusIds);
		ew.eq("goods_list_out_flag", "N");
		return restfulResponse.response(goodsListService.selectList(ew), RequestType.GET);
	}
	
	@RequestMapping(method=RequestMethod.GET)
	public Object query(StockOut stockOut,String dateScope,Integer limit,Integer offset){
		EntityWrapper<StockOut> ew = 
				MyBatisPlusUtils.getTimeScopeCondition(stockOut, dateScope, "stock_in_input_time");
		Page<StockOut> page = new Page<StockOut>(offset,limit);
		Page<StockOut> pageData = stockOutService.selectPage(page, ew);
		BootstrapTablePageVO bootVO = 
		    new BootstrapTablePageVO(pageData.getPages(),pageData.getTotal(),pageData.getRecords());
		return restfulResponse.response(bootVO,RequestType.GET);
	}
	
	/**
	 * 添加 出库信息
	 * 
	 * @param jsonObjs
	 * 			DTO对象,传递过来的Json必须包含array和obj两个key
	 * 
	 * @return restful 风格 Http状态码
	 * @throws Exception 
	 */
	@RequestMapping(method=RequestMethod.POST)
	public Object add(@RequestBody JsonObjsVO<GoodsList,StockOut> jsonObjs) throws Exception{
		StockOut outOrderInfo = jsonObjs.getObj();
		List<GoodsList> outGoods = jsonObjs.getArray();
		//设置单号
		outOrderInfo.setStockOutOrderNumber(MyBatisPlusUtils.getOutOrderNumber());
		//设置出库时间
		outOrderInfo.setStockOutTime(new Date());
		//判断是否需要记录
		if(outOrderInfo.getStockOutStatus().equals("出库完成")) {
			flag = addFinishOutProduct(outGoods,outOrderInfo);
		}
		if(flag) {
			//拆分订单
			Map<String, List<GoodsList>> splitResultMap = splitGoods(outGoods);
			isNormalFinish = stockOutService.addStockOutOrder(splitResultMap,outOrderInfo);
		}
		return restfulResponse.response(isNormalFinish,RequestType.POST);
	}
	
	/**
	 * 删除 出库单选中的产品
	 * 
	 * @param  ids
	 * 			  需要删除的记录的id号
	 * 
	 * @return restful风格 Http状态码 Void
	 */
	@RequestMapping(value="/goods-list/{ids}",method=RequestMethod.DELETE)
	public Object removeGoodsById(@PathVariable("ids") String ids){
		GoodsList goods = new GoodsList();
		goods.setGoodsListOutFlag("N");
		goods.setGoodsListOutStockOrderNumber("0");
		goods.setGoodsListOperatLog(
		    new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒").
		        format(new Date())+"该货物从出库单中删除-操作用户:"+getCurrentUser().getUseAuthor()
		);
		List<String> idList = WarpperStringUtils.getIdListByCommaSplit(ids);
		isNormalFinish = goodsListService.update(goods,
		    new EntityWrapper<GoodsList>().in("goods_list_product_id", idList)
		);
		return restfulResponse.response(isNormalFinish,RequestType.DELETE);
	}

	/**
	 * 更新 出库信息
	 * 
	 * @param jsonObjs
	 * 			DTO对象,传递过来的Json必须包含array和obj两个key
	 * 
	 * @return restful 风格 Http状态码
	 */
	@RequestMapping(method=RequestMethod.PUT)
	public Object update(@RequestBody JsonObjsVO<GoodsList,StockOut> jsonObjs){
		StockOut outOrderInfo = jsonObjs.getObj();
		List<GoodsList> outGoods = jsonObjs.getArray();
		//判断是否需要记录
		if(outOrderInfo.getStockOutStatus().equals("出库完成")) {
			flag = addFinishOutProduct(outGoods,outOrderInfo);
		}
		if(flag) {
			//货物比原来出库少
			ArrayList<GoodsList> decreaseGoodsList = new ArrayList<GoodsList>();
			//货物比原来出库多
			ArrayList<GoodsList> increaseGoodsList = new ArrayList<GoodsList>();
			//不打算出库的货物
			ArrayList<GoodsList> backRepository = new ArrayList<GoodsList>();
			//区分数据
			for (GoodsList goodsList : outGoods) {
				if(goodsList.getChecked() == false || goodsList.getGoodsListOutStockCount() == 0) {
					//不出库的情况
					backRepository.add(goodsList);
				}else if(goodsList.getGoodsListOutStockCount() < goodsList.getTempOutStockCount() && goodsList.getChecked() == true) {
					//减少的情况
					decreaseGoodsList.add(goodsList);
				}else if(goodsList.getGoodsListOutStockCount() > goodsList.getTempOutStockCount() && goodsList.getChecked() == true){
					//增加的情况
					increaseGoodsList.add(goodsList);
				}
			}
			isNormalFinish =  stockOutService.updateGoodsListAndStockOut(decreaseGoodsList,increaseGoodsList,backRepository,outOrderInfo);
		}
		return restfulResponse.response(isNormalFinish,RequestType.PUT);
	}
	
	/**
	 * 删除出库单
	 */
	@RequestMapping(value = "{ids}",method=RequestMethod.DELETE)
	public Object delete(@PathVariable("ids") String idStr) {
		List<String> ids = WarpperStringUtils.getIdListByCommaSplit(idStr);
		isNormalFinish = stockOutService.removeStockOutOrder(ids);
		return restfulResponse.response(isNormalFinish,RequestType.DELETE);
	}
}
